/******************************************************************************
Project    : Real time rtsp server library base on live555
*******************************************************************************
File Name    :  <AudioRTimeServerMediaSubsession.cpp>:  audio real time SMSS source file
Module Name  :  
Description  :  None
History      :
 No.   Ver.     Date        Designed by  Comment
-----+--------+----------+------------+---------------------------------------
 001   0.00.01  06/08/2015  <3G@LIURENHUA>   <audio real time SMSS source file>
*******************************************************************************/
#include <pthread.h>
#include "AmrRTimeFramedSource.h"
#include "AdtsRTimeFramedSource.h"
#include "AudioRTimeServerMediaSubsession.h"

/******************************************************************************
  class functions define
 ******************************************************************************/
AudioRTimeServerMediaSubsession * AudioRTimeServerMediaSubsession::createNew(
							UsageEnvironment & env, 
							const tEsFmt eCodecId,
#ifdef LOCAL_SOCK_INPUT
							const char  *pcIdentity,
#endif /* LOCAL_SOCK_INPUT */
							const CH_CFG_et eChCfg,
							const FS_IDX_et eFsIdx,
							const PROFILE_et eProfile,
							const Boolean bWideBand,
							const u_int8_t ucChNum,
#ifdef LOCAL_SOCK_INPUT
							const u_int32_t unSBufSize, 
							const u_int32_t unRBufSize
#else
							queue_t *pstQue
#endif /* LOCAL_SOCK_INPUT */
							)
{
	return new AudioRTimeServerMediaSubsession(env,
							eCodecId, 
#ifdef LOCAL_SOCK_INPUT
							pcIdentity, 
#endif /* LOCAL_SOCK_INPUT */
							eChCfg, 
							eFsIdx, 
							eProfile, 
							bWideBand,
							ucChNum,
#ifdef LOCAL_SOCK_INPUT
							unSBufSize,
							unRBufSize
#else
							pstQue
#endif /* LOCAL_SOCK_INPUT */
							);
}

AudioRTimeServerMediaSubsession::AudioRTimeServerMediaSubsession(
							UsageEnvironment & env,
							const tEsFmt eCodecId,
#ifdef LOCAL_SOCK_INPUT
							const char  *pcIdentity,
#endif /* LOCAL_SOCK_INPUT */
							const CH_CFG_et eChCfg,
							const FS_IDX_et eFsIdx,
							const PROFILE_et eProfile,
							const Boolean bWideBand,
							const u_int8_t ucChNum,
#ifdef LOCAL_SOCK_INPUT
							const u_int32_t unSBufSize, 
							const u_int32_t unRBufSize
#else
							queue_t *pstQue
#endif /* LOCAL_SOCK_INPUT */
							) : OnDemandServerMediaSubsession(env, True)
{
	m_eCodecId = eCodecId;

#ifdef LOCAL_SOCK_INPUT
	/* Local socket identity checking */
	if( (NULL != pcIdentity) ){
		snprintf(m_cIdentity, LSOCK_ID_LENGTH, "%s", pcIdentity);
	}else{
		int nSMSSCnt = 0;
		pthread_mutex_lock(&gMutex);
		nSMSSCnt = gSMSSCnt++;
		pthread_mutex_unlock(&gMutex);
		snprintf(m_cIdentity, LSOCK_ID_LENGTH, 
			"%s_ch%d", LOCAL_SOCKET_ID, nSMSSCnt);
		rtsp_db_info("ID=%s", m_cIdentity);
	}
#else
	m_que = pstQue;
#endif /* LOCAL_SOCK_INPUT */

	m_eChCfg = eChCfg;
	rtsp_db_info("m_eChCfg=%d", m_eChCfg);
	m_eFsIdx = eFsIdx;
	rtsp_db_info("m_eFsIdx=%d", m_eFsIdx);
	m_eProfile = eProfile;
	rtsp_db_info("m_eProfile=%d", m_eProfile);
	m_bWideBand = bWideBand;
	rtsp_db_info("m_bWideBand=%d", m_bWideBand);
	m_ucChNum = ucChNum;
	rtsp_db_info("m_ucChNum=%d", m_ucChNum);
	
#ifdef LOCAL_SOCK_INPUT
	m_unSBufSize = unSBufSize;
	rtsp_db_info("m_unSBufSize=%d", m_unSBufSize);
	m_unRBufSize = unRBufSize;
	rtsp_db_info("m_unRBufSize=%d", m_unRBufSize);
#endif /* LOCAL_SOCK_INPUT */
}

FramedSource *AudioRTimeServerMediaSubsession::createNewStreamSource(
	unsigned clientSessionId, unsigned & estBitrate)
{
	FramedSource *pctFrmSource = NULL;

	/* Check codec type */
	switch( (m_eCodecId) ){
	case AUDIO_FORMAT_ADTS:
		//estBitrate = 96;	// kbps, estimate
		pctFrmSource = 
			ADtsRTimeFramedSource::createNew(
				envir(), 
#ifdef LOCAL_SOCK_INPUT
				m_cIdentity, 
#endif /* LOCAL_SOCK_INPUT */
				m_eChCfg, 
				m_eFsIdx,
				m_eProfile, 
#ifdef LOCAL_SOCK_INPUT
				m_unSBufSize, 
				m_unRBufSize
#else
				m_que
#endif /* LOCAL_SOCK_INPUT */
				);
		break;
	case AUDIO_FORMAT_AMR:
		//estBitrate = 10; // kbps, estimate
		pctFrmSource = 
			AmrRTimeFramedSource::createNew(
				envir(), 
#ifdef LOCAL_SOCK_INPUT
				m_cIdentity,
#endif /* LOCAL_SOCK_INPUT */
				m_bWideBand, 
				m_ucChNum,
#ifdef LOCAL_SOCK_INPUT
				m_unSBufSize, 
				m_unRBufSize
#else
				m_que
#endif /* LOCAL_SOCK_INPUT */
				);
		break;
	default:
		printf("[%s]unsupport codec type\n", __func__);
		break;
	}
	return pctFrmSource;
}

RTPSink *AudioRTimeServerMediaSubsession::createNewRTPSink(
	Groupsock * rtpGroupsock, 
	unsigned char rtpPayloadTypeIfDynamic, 
	FramedSource * inputSource)
{
	RTPSink *pctRtpSink = NULL;
	/* Check codec type */
	switch( (m_eCodecId) ){
	case AUDIO_FORMAT_ADTS:
		{
			ADtsRTimeFramedSource* adtsSource = 
				(ADtsRTimeFramedSource*)inputSource;
			pctRtpSink = 
				MPEG4GenericRTPSink::createNew(envir(), 
				rtpGroupsock, rtpPayloadTypeIfDynamic,
				adtsSource->samplingFrequency(),
				"audio", "AAC-hbr", adtsSource->configStr(),
				adtsSource->numChannels());
		}
		break;
	case AUDIO_FORMAT_AMR:
		{
			AmrRTimeFramedSource* amrSource = 
				(AmrRTimeFramedSource*)inputSource;
			pctRtpSink = AMRAudioRTPSink::createNew(envir(), 
				rtpGroupsock, rtpPayloadTypeIfDynamic,
				amrSource->isWideband(),
				amrSource->numChannels());
		}
		break;
	default:
		printf("[%s]unsupport codec type\n", __func__);
		break;
	}
	return pctRtpSink;
}
